package cn.car.biz.carAccess.eventListener;

import cn.car.biz.carAccess.cache.VehiclePlateResultCache;
import cn.car.biz.carAccess.event.GIoInResultEvent;
import cn.car.biz.carAccess.event.VehicleRecordPutGovEvent;
import cn.car.constants.CarAccessConstants;
import cn.car.domains.ctx.PlateDetectedContext;
import cn.car.domains.entity.CameraInfoEntity;
import cn.car.domains.entity.CameraSnapshotEntity;
import cn.car.domains.enums.CameraWorkModeEnum;
import cn.car.domains.enums.GIoInTypeEnum;
import cn.car.domains.enums.VehicleSnapshotTypeEnum;
import cn.car.domains.enums.VehicleTypeEnum;
import cn.car.exception.CarAccessControlException;
import cn.car.service.CameraService;
import cn.car.service.CameraSnapshotService;
import cn.car.service.VehicleEntryExitLedgerInfoService;
import cn.car.utils.Base64ToImageUtil;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.context.ApplicationListener;
import org.springframework.stereotype.Component;

import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.Base64;
import java.util.Date;
import java.util.Objects;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.function.Supplier;

@Component
@Slf4j
public class  GIoInResultEventListenerHeadMidTailSnapshot implements ApplicationListener<GIoInResultEvent> {

    @Resource
    private CameraService cameraService;

    @Resource
    private CameraSnapshotService cameraSnapshotService;

    @Resource
    private VehicleEntryExitLedgerInfoService vehicleEntryExitLedgerInfoService;

    @Resource
    private ApplicationEventPublisher publisher;

    @Resource
    private VehiclePlateResultCache vehiclePlateResultCache;



    ScheduledThreadPoolExecutor scheduler = new ScheduledThreadPoolExecutor(
            2
    );

    private static final Supplier<String> IMAGE_LEDGER = () -> String.join(File.separator, CarAccessConstants.getPictureFilePath().get(), "ledger");


    @Override
    public boolean supportsAsyncExecution() {
        return true;
    }

    @Override
    public void onApplicationEvent(GIoInResultEvent event) {
        PlateDetectedContext context = event.getContext();

        if (context == null) {
            return;
        }

        if (!VehicleTypeEnum.ENTRY_EXIT.name().equals(context.getVehicleCommonInfoEntity().getVehicleType())) {
            return;
        }

        //String gIoInType = context.getGIoInType();

        if (Objects.equals(context.getGIoInType(), GIoInTypeEnum.up.name())) {

            //保存车头照
            doEvent(context, VehicleSnapshotTypeEnum.HEAD);
            //5秒后保存车中照
            scheduler.schedule(() -> doEvent(context, VehicleSnapshotTypeEnum.MID), 5, TimeUnit.SECONDS);
        } else {

            //保存车尾照
            doEvent(context, VehicleSnapshotTypeEnum.TAIL);

            //上报政府
            VehicleRecordPutGovEvent plateDetectResultEvent = new VehicleRecordPutGovEvent(this, context);
            publisher.publishEvent(plateDetectResultEvent);

            //删除缓存
            vehiclePlateResultCache.remove(context.getCameraInfoEntity().getCameraIp());
        }

    }


    private void doEvent(PlateDetectedContext context, VehicleSnapshotTypeEnum vehicleSnapshotTypeEnum) {


        CameraInfoEntity cameraInfoEntity = context.getCameraInfoEntity();
        CameraInfoEntity snapCamera = cameraService.getCameraById(cameraInfoEntity.getAssociationCameraId());

        if (snapCamera == null || !CameraWorkModeEnum.SNAP.name().equals(snapCamera.getWorkMode())) {
            throw CarAccessControlException.DATE_NOT_EXIST.newInstance("[HeadMidTailSnapshot Event] snap camera not exist detected camera ip:" + cameraInfoEntity.getCameraIp());
        }

        Date now = new Date();
        CameraSnapshotEntity lastCameraSnapshotEntity = cameraSnapshotService.getLastSnapshot(snapCamera.getCameraIp(), now);


        final String fileName = System.currentTimeMillis() + ".jpeg";
        final String fileDir = String.join(File.separator, IMAGE_LEDGER.get());
        final String filePath = String.join(File.separator, fileDir, fileName);
        //转换图片

        try {
            final byte[] fileBytes = Files.readAllBytes(Paths.get(lastCameraSnapshotEntity.getSnapshotPath()));
            final String base64String = Base64.getEncoder().encodeToString(fileBytes);
            Base64ToImageUtil.saveBase64ImageToFile(base64String, filePath);
        } catch (IOException e) {
            log.error(e.getMessage(), e);
        }

        vehicleEntryExitLedgerInfoService.recordHeadTailImg(context.getVehicleCommonLedgerInfoEntity().getAssociationId(), filePath, context.getInOutType(), vehicleSnapshotTypeEnum);


    }
}
